home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / box < prev    next >
Encoding:
Text File  |  1988-04-18  |  26.7 KB  |  912 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *              box.c
  10.  */
  11.  
  12. #include "tex.h"
  13. #include "texext.h"
  14. #include "arith.h"
  15. #include "heap.h"
  16. #include "char.h"
  17. #include "str.h"
  18. #include "eq.h"
  19. #include "hash.h"
  20. #include "tfm.h"
  21. #include "print.h"
  22. #include "math.h"
  23. #include "box.h"
  24. #include "token.h"
  25. #include "tokenlists.h"
  26.  
  27. val             depth_threshold;
  28. val             breadth_max;
  29. fnt             font_in_short_display;
  30.  
  31. ptr
  32. new_null_box ()
  33. {
  34.         ptr             p;
  35.  
  36.         p = get_node(BOX_NODE_SIZE);
  37.         type(p) = HLIST_NODE;
  38.         subtype(p) = MIN_QUARTERWORD;
  39.         width(p) = 0;
  40.         depth(p) = 0;
  41.         height(p) = 0;
  42.         shift_amount(p) = 0;
  43.         list_ptr(p) = NULL;
  44.         glue_sign(p) = NORMAL;
  45.         glue_order(p) = NORMAL;
  46.         glue_set(p) = 0.0;
  47.  
  48.         return p;
  49. }
  50.  
  51. ptr
  52. new_rule ()
  53. {
  54.         ptr              p;
  55.  
  56.         p = get_node(RULE_NODE_SIZE);
  57.         type(p) = RULE_NODE;
  58.         subtype(p) = 0;
  59.         width(p) = NULL_FLAG;
  60.         depth(p) = NULL_FLAG;
  61.         height(p) = NULL_FLAG;
  62.  
  63.         return p;
  64. }
  65.  
  66. ptr
  67. new_ligature (f, c, q)
  68.         qword   f;
  69.         qword   c;
  70.         ptr             q;
  71. {
  72.         ptr             p;
  73.  
  74.         p = get_node(SMALL_NODE_SIZE);
  75.         type(p) = LIGATURE_NODE;
  76.         subtype(p) = 0;
  77.         font(lig_char(p)) = f;
  78.         character(lig_char(p)) = c;
  79.         lig_ptr(p) = q;
  80.  
  81.         return p;
  82. }
  83.  
  84. ptr
  85. new_disc ()
  86. {
  87.         ptr             p;
  88.  
  89.         p = get_node(SMALL_NODE_SIZE);
  90.         type(p) = DISC_NODE;
  91.         replace_count(p) = 0;
  92.         pre_break(p) = NULL;
  93.         post_break(p) = NULL;
  94.  
  95.         return p;
  96. }
  97.  
  98. ptr
  99. new_math (w, s)
  100.         scal    w;
  101.         int             s;
  102. {
  103.         ptr             p;
  104.  
  105.         p = get_node(SMALL_NODE_SIZE);
  106.         type(p) = MATH_NODE;
  107.         subtype(p) = s;
  108.         width(p) = w;
  109.  
  110.         return p;
  111. }
  112.  
  113. ptr
  114. new_spec (p)
  115.         ptr             p;
  116. {
  117.         ptr             q;
  118.  
  119.         q = get_node(GLUE_SPEC_SIZE);
  120.         mem[q] = mem[p];
  121.         glue_ref_count(q) = NULL;
  122.         width(q) = width(p);
  123.         stretch(q) = stretch(p);
  124.         shrink(q) = shrink(p);
  125.  
  126.         return q;
  127. }
  128.  
  129. ptr
  130. new_param_glue (n)
  131.         int             n;
  132. {
  133.         ptr             p;
  134.         ptr             q;
  135.  
  136.         p = get_node(SMALL_NODE_SIZE);
  137.         type(p) = GLUE_NODE;
  138.         subtype(p) = n + 1;
  139.         leader_ptr(p) = NULL;
  140.         q = glue_par(n);
  141.         glue_ptr(p) = q;
  142.         incr(glue_ref_count(q));
  143.  
  144.         return p;
  145. }
  146.  
  147. ptr
  148. new_glue (q)
  149.         ptr             q;
  150. {
  151.         ptr             p;
  152.  
  153.         p = get_node(SMALL_NODE_SIZE);
  154.         type(p) = GLUE_NODE;
  155.         subtype(p) = NORMAL;
  156.         leader_ptr(p) = NULL;
  157.         glue_ptr(p) = q;
  158.         incr(glue_ref_count(q));
  159.  
  160.         return p;
  161. }
  162.  
  163. ptr
  164. new_skip_param (n)
  165.         int             n;
  166. {
  167.         ptr             p;
  168.  
  169.         temp_ptr = new_spec(glue_par(n));
  170.         p = new_glue(temp_ptr);
  171.         glue_ref_count(temp_ptr) = NULL;
  172.         subtype(p) = n + 1;
  173.  
  174.         return p;
  175. }
  176.  
  177. ptr
  178. new_kern (w)
  179.         scal    w;
  180. {
  181.         ptr             p;
  182.  
  183.         p = get_node(SMALL_NODE_SIZE);
  184.         type(p) = KERN_NODE;
  185.         subtype(p) = NORMAL;
  186.         width(p) = w;
  187.  
  188.         return p;
  189. }
  190.  
  191. ptr
  192. new_penalty (m)
  193.         val             m;
  194. {
  195.         ptr             p;
  196.  
  197.         p = get_node(SMALL_NODE_SIZE);
  198.         type(p) = PENALTY_NODE;
  199.         subtype(p) = 0;
  200.         penalty(p) = m;
  201.  
  202.         return p;
  203. }
  204.  
  205. print_font_and_char (p)
  206.         ptr             p;
  207. {
  208.         if (p > mem_end)
  209.                 print_esc("CLOBBERED.");
  210.         else {
  211.                 if (font(p) < FONT_BASE || font(p) > FONT_MAX)
  212.                         print_char('*');
  213.                 else {
  214.                         print_esc("");
  215.                         print_str(font_id_text(font(p)));
  216.                         print_char(' ');
  217.                         print_ASCII(qo(character(p)));
  218.                 }
  219.         }
  220. }
  221.  
  222. print_mark (p)
  223.         ptr             p;
  224. {
  225.         print_char('{');
  226.         if (p < 0 || p > tok_end)
  227.                 print_esc("CLOBBERED.");
  228.         else show_token_list(token_link(p), NULL, (val) MAX_PRINT_LINE - 10);
  229.         print_char('}');
  230. }
  231.  
  232. print_rule_dimen (d)
  233.         scal    d;
  234. {
  235.         if (is_running(d))
  236.                 print_char('*');
  237.         else print_scaled(d);
  238. }
  239.  
  240. print_glue (d, o, s)
  241.         scal    d;
  242.         qword   o;
  243.         char*   s;
  244. {
  245.         print_scaled(d);
  246.         if (o < NORMAL || o > FILLL)
  247.                 print("foul");
  248.         else if (o > NORMAL) {
  249.                 print("fil");
  250.                 while  (o >  FIL) {
  251.                         print_char('l');
  252.                         decr(o);
  253.                 }
  254.         } else if (s)
  255.                 print(s);
  256. }
  257.  
  258. print_spec (p, s)
  259.         ptr             p;
  260.         char*   s;
  261. {
  262.         if (p < MEM_MIN || p >= hi_mem_min)
  263.                 print_char('*');
  264.         else {
  265.                 print_scaled(width(p));
  266.                 if (s) print(s);/*DIFF*/
  267.                 if (stretch(p) != 0) {
  268.                         print(" plus ");
  269.                         print_glue(stretch(p), stretch_order(p), s);
  270.                 }
  271.                 if (shrink(p) != 0) {
  272.                         print(" minus ");
  273.                         print_glue(shrink(p), shrink_order(p), s);
  274.                 }
  275.         }
  276. }
  277.  
  278. short_display (p)
  279.         ptr             p;
  280. {
  281.         int             n;
  282.  
  283.         for (p; p > MEM_MIN; p = link(p)) {/*DIFF*/
  284.                 if (is_char_node(p) && p <= mem_end) {
  285.                         if (font(p) != font_in_short_display) {
  286.                                 if (font(p) < FONT_BASE || font(p) > FONT_MAX) 
  287.                                         print_char('*');
  288.                                 else {
  289.                                         print_esc("");
  290.                                         print_str(font_id_text(font(p)));
  291.                                 }
  292.                                 print_char(' ');
  293.                                 font_in_short_display = font(p);
  294.                         }
  295.                         print_ASCII(qo(character(p)));
  296.                 } else {
  297.                         switch (type(p))
  298.                         {
  299.                         case HLIST_NODE:
  300.                         case VLIST_NODE: 
  301.                         case INS_NODE:
  302.                         case WHATSIT_NODE:
  303.                         case MARK_NODE:
  304.                         case ADJUST_NODE:
  305.                         case UNSET_NODE:
  306.                                 print("[]");
  307.                                 break;
  308.  
  309.                         case RULE_NODE:
  310.                                 print_char('|');
  311.                                 break;
  312.  
  313.                         case GLUE_NODE:
  314.                                 if (glue_ptr(p) != zero_glue)
  315.                                         print_char(' ');
  316.                                 break;
  317.  
  318.                         case MATH_NODE:
  319.                                 print_char('$');
  320.                                 break;
  321.  
  322.                         case LIGATURE_NODE:
  323.                                 short_display(lig_ptr(p));
  324.                                 break;
  325.  
  326.                         case DISC_NODE:
  327.                                 short_display(pre_break(p));
  328.                                 short_display(post_break(p));
  329.                                 n = replace_count(p);
  330.                                 while (n > 0) {
  331.                                         if (link(p) != NULL)
  332.                                                 p = link(p);
  333.                                         decr(n);
  334.                                 }
  335.                                 break;
  336.  
  337.                         default:
  338.                                 break;
  339.                         }
  340.                 }
  341.         }
  342. }
  343.  
  344. show_box (p)
  345.         ptr             p;
  346. {
  347.         depth_threshold = show_box_depth;
  348.         breadth_max = show_box_breadth;
  349.         if (breadth_max <= 0)
  350.                 breadth_max = 5;
  351.         if (pool_ptr + depth_threshold >= POOL_SIZE)
  352.                 depth_threshold = POOL_SIZE - pool_ptr - 1;
  353.         show_node_list(p);
  354.         print_ln();
  355. }
  356.  
  357. show_box1 (p)
  358.         ptr             p;
  359. {
  360.         if (type(p) == HLIST_NODE)
  361.                 print_esc("h");
  362.         else if (type(p) == VLIST_NODE)
  363.                 print_esc("v");
  364.         else print_esc("unset");
  365.         print("box(");
  366.         print_scaled(height(p));
  367.         print_char('+') ;
  368.         print_scaled(depth(p));
  369.         print(")x")     ;
  370.         print_scaled(width(p));
  371.         if (type(p) == UNSET_NODE) {
  372.                 if (span_count(p) != MIN_QUARTERWORD) {
  373.                         print(" (");
  374.                         print_int(qo(span_count(p))+1);
  375.                         print(" columns)");
  376.                 }
  377.                 if (glue_stretch(p) != 0) {
  378.                         print(", stretch ");
  379.                         print_glue(glue_stretch(p), glue_order(p), "");
  380.                 }
  381.                 if (glue_shrink(p) != 0) {
  382.                         print(", shrink ");
  383.                         print_glue(glue_shrink(p), glue_sign(p), "");
  384.                 }
  385.         } else {
  386.                 show_glue_set(p);
  387.                 if (shift_amount(p) != 0) {
  388.                         print(", shifted ");
  389.                         print_scaled(shift_amount(p));
  390.                 }
  391.         }
  392.         node_list_display(list_ptr(p));
  393. }
  394.  
  395. show_glue_set (p)
  396.         ptr             p;
  397. {
  398.         if (glue_set(p) != 0 && glue_sign(p) != NORMAL) {
  399.                 print(", glue set ");
  400.                 if (glue_sign(p) == SHRINKING)
  401.                         print("- ");
  402.                 if (abs(glue_set(p)) > 20000.0) {
  403.                         if (glue_set(p) > 0)
  404.                                 print_char('>');
  405.                         else print("< -");
  406.                         print_glue(20000 * UNITY, glue_order(p), "");
  407.                 } else
  408.                         print_glue(round(glue_set(p) * UNITY), glue_order(p), "");
  409.         }
  410. }
  411.  
  412. show_rule (p)
  413.         ptr             p;
  414. {
  415.         print_esc("rule(");
  416.         print_rule_dimen(height(p));
  417.         print_char('+');
  418.         print_rule_dimen(depth(p));
  419.         print(")x");
  420.         print_rule_dimen(width(p));
  421. }
  422.  
  423. show_insertion (p)
  424.         ptr             p;
  425. {
  426.         print_esc("insert");
  427.         print_int(qo(subtype(p)));
  428.         print(", natural size ");
  429.         print_scaled(height(p));
  430.         print("; split(");
  431.         print_spec(split_top_ptr(p), "");
  432.         print_char(',');
  433.         print_scaled(depth(p));
  434.         print("); float cost ");
  435.         print_val(float_cost(p));
  436.         node_list_display(ins_ptr(p));
  437. }
  438.  
  439. show_leaders (p)
  440.         ptr             p;
  441. {
  442.         print_esc("");
  443.         if (subtype(p) == C_LEADERS)
  444.                 print_char('c');
  445.         else if (subtype(p) == X_LEADERS)
  446.                 print_char('x');
  447.         print("leaders ");
  448.         print_spec(glue_ptr(p), "");
  449.         node_list_display(leader_ptr(p));
  450. }
  451.  
  452. show_glue (p)
  453.         ptr             p;
  454. {
  455.         if (subtype(p) >= A_LEADERS)
  456.                 show_leaders(p);
  457.         else {
  458.                 print_esc("glue");
  459.                 if (subtype(p) != NORMAL) {
  460.                         print_char('(');
  461.                         if (subtype(p) < COND_MATH_GLUE)
  462.                                 print_skip_param(subtype(p) - 1);
  463.                         else if (subtype(p) == COND_MATH_GLUE)
  464.                                 print_esc("nonscript");
  465.                         else print_esc("mskip");
  466.                         print_char(')');
  467.                 }
  468.                 if (subtype(p) != COND_MATH_GLUE) {
  469.                         print_char(' ');
  470.                         if (subtype(p) < COND_MATH_GLUE)
  471.                                 print_spec(glue_ptr(p), "");
  472.                         else print_spec(glue_ptr(p), "mu");
  473.                 }
  474.         }
  475. }
  476.  
  477. show_kern (p)
  478.         ptr             p;
  479. {
  480.         if (subtype(p) != MU_GLUE) {
  481.                 print_esc("kern");
  482.                 if (subtype(p) != NORMAL)
  483.                         print_char(' ');
  484.                 print_scaled(width(p));
  485.                 if (subtype(p) == ACC_KERN)
  486.                         print(" (for accent)");}
  487.         else {
  488.                 print_esc("mkern");
  489.                 print_scaled(width(p));
  490.                 print("mu");
  491.         }
  492. }
  493.  
  494. show_math (p)
  495.         ptr             p;
  496. {
  497.         print_esc("math");
  498.         if (subtype(p) == BEFORE)
  499.                 print("on");
  500.         else print("off");
  501.         if (width(p) != 0) {
  502.                 print(", surrounded ");
  503.                 print_scaled(width(p));
  504.         }
  505. }
  506.         
  507. show_ligature (p)
  508.         ptr             p;
  509. {
  510.         print_font_and_char(lig_char(p));
  511.         print(" (ligature ");
  512.         font_in_short_display = font(lig_char(p));
  513.         short_display(lig_ptr(p));
  514.         print_char(')');
  515. }
  516.  
  517. show_discretionary (p)
  518.         ptr             p;
  519. {
  520.         print_esc("discretionary");
  521.         if (replace_count(p) > 0) {
  522.                 print(" replacing ");
  523.                 print_int(replace_count(p));
  524.         }
  525.         node_list_display(pre_break(p));
  526.         append_char('|');
  527.         show_node_list(post_break(p));
  528.         flush_char();
  529. }
  530.  
  531. show_penalty (p)
  532.         ptr             p;
  533. {
  534.         print_esc("penalty ");
  535.         print_val(penalty(p));
  536. }
  537.  
  538. show_mark (p)
  539.         ptr             p;
  540. {
  541.         print_esc("mark");
  542.         print_mark(mark_ptr(p));
  543. }
  544.  
  545. show_adjust (p)
  546.         ptr             p;
  547. {
  548.         print_esc("vadjust");
  549.         node_list_display(adjust_ptr(p));
  550. }
  551.  
  552. show_node_list (p)
  553.         int     p;/*DIFF*/
  554. {
  555.         int             n;
  556.  
  557.         if (cur_length() > depth_threshold) {
  558.                 if (p > NULL)
  559.                         print(" []");
  560.                 return;
  561.         }
  562.         n = 0;
  563.         while (p > MEM_MIN) {/*DIFF*/
  564.                 print_ln();
  565.                 print_current_string();
  566.                 if (p > mem_end) {
  567.                         print("Bad link, display aborted.");
  568.                         return;
  569.                 }
  570.                 incr(n);
  571.                 if (n > breadth_max) {
  572.                         print("etc.");
  573.                         return;
  574.                 }
  575.                 if (is_char_node(p))
  576.                         print_font_and_char(p);
  577.                 else {
  578.                         switch (type(p))
  579.                         {
  580.                         case HLIST_NODE:
  581.                         case VLIST_NODE:
  582.                         case UNSET_NODE:
  583.                                 show_box1(p);
  584.                                 break;
  585.  
  586.                         case RULE_NODE:
  587.                                 show_rule(p);
  588.                                 break;
  589.                         
  590.                         case INS_NODE:
  591.                                 show_insertion(p);
  592.                                 break;
  593.                         
  594.                         case WHATSIT_NODE:
  595.                                 show_whatsit(p);
  596.                                 break;
  597.                         
  598.                         case GLUE_NODE:
  599.                                 show_glue(p);
  600.                                 break;
  601.                         
  602.                         case KERN_NODE:
  603.                                 show_kern(p);
  604.                                 break;
  605.                         
  606.                         case MATH_NODE:
  607.                                 show_math(p);
  608.                                 break;
  609.                         
  610.                         case LIGATURE_NODE:
  611.                                 show_ligature(p);
  612.                                 break;
  613.  
  614.                         case PENALTY_NODE:
  615.                                 show_penalty(p);
  616.                                 break;
  617.                 
  618.                         case DISC_NODE:
  619.                                 show_discretionary(p);
  620.                                 break;
  621.                         
  622.                         case MARK_NODE:
  623.                                 show_mark(p);
  624.                                 break;
  625.                         
  626.                         case ADJUST_NODE:
  627.                                 show_adjust(p);
  628.                                 break;
  629.                         
  630.                         case STYLE_NODE:
  631.                                 print_style(subtype(p));
  632.                                 break;
  633.                         
  634.                         case CHOICE_NODE:
  635.                                 show_choice_node(p);
  636.                                 break;
  637.  
  638.                         case INNER_NOAD:
  639.                         case ORD_NOAD:
  640.                         case OP_NOAD:
  641.                         case BIN_NOAD:
  642.                         case REL_NOAD:
  643.                         case OPEN_NOAD:
  644.                         case CLOSE_NOAD:
  645.                         case PUNCT_NOAD:
  646.                         case RADICAL_NOAD:
  647.                         case OVER_NOAD:
  648.                         case UNDER_NOAD:
  649.                         case VCENTER_NOAD:
  650.                         case ACCENT_NOAD:
  651.                         case LEFT_NOAD:
  652.                         case RIGHT_NOAD:
  653.                                 show_normal_noad(p);
  654.                                 break;
  655.                         
  656.                         case FRACTION_NOAD:
  657.                                 show_fraction_noad(p);
  658.                                 break;
  659.  
  660.                         default:
  661.                                 print("Unknown node type!");
  662.                                 break;
  663.                         }
  664.                 }
  665.                 p = link(p);
  666.         }
  667. }
  668.  
  669. show_info ()
  670. {
  671.         show_node_list(info(temp_ptr));
  672. }
  673.  
  674. delete_glue_ref (p)
  675.         ptr             p;
  676. {
  677.         if (glue_ref_count(p) == NULL)
  678.                 free_node(p, GLUE_SPEC_SIZE);
  679.         else decr(glue_ref_count(p));
  680. }
  681.  
  682. flush_node_list (p)
  683.         ptr             p;
  684. {
  685.         ptr             q;
  686.  
  687.         while (p != NULL) {
  688.                 q = link(p);
  689.                 if (is_char_node(p)) {
  690.                         free_avail(p);
  691.                 } else {
  692.                         switch (type(p))
  693.                         {
  694.                         case HLIST_NODE:
  695.                         case VLIST_NODE:
  696.                         case UNSET_NODE:
  697.                                 flush_node_list(list_ptr(p));
  698.                                 free_node(p, BOX_NODE_SIZE);
  699.                                 goto done;
  700.                                 break;
  701.                                         
  702.                         case RULE_NODE:
  703.                                 free_node(p, RULE_NODE_SIZE);
  704.                                 goto done;
  705.                                 break;
  706.  
  707.                         case INS_NODE:
  708.                                 flush_node_list(ins_ptr(p));
  709.                                 delete_glue_ref(split_top_ptr(p));
  710.                                 free_node(p, INS_NODE_SIZE);
  711.                                 goto done;
  712.                                 break;
  713.  
  714.                         case WHATSIT_NODE:
  715.                                 free_whatsit(p);
  716.                                 goto done;
  717.                                 break;
  718.                         
  719.                         case GLUE_NODE:
  720.                                 fast_delete_glue_ref(glue_ptr(p));
  721.                                 if (leader_ptr(p) != NULL)
  722.                                         flush_node_list(leader_ptr(p));
  723.                                 break;
  724.  
  725.                         case KERN_NODE:
  726.                         case MATH_NODE:
  727.                         case PENALTY_NODE:
  728.                                 break;
  729.  
  730.                         case LIGATURE_NODE:
  731.                                 flush_node_list(lig_ptr(p));
  732.                                 break;
  733.  
  734.                         case MARK_NODE:
  735.                                 delete_token_ref(mark_ptr(p));
  736.                                 break;
  737.                         
  738.                         case DISC_NODE:
  739.                                 flush_node_list(pre_break(p));
  740.                                 flush_node_list(post_break(p));
  741.                                 break;
  742.  
  743.                         case ADJUST_NODE:
  744.                                 flush_node_list(adjust_ptr(p));
  745.                                 break;
  746.  
  747.                         case STYLE_NODE:
  748.                                 free_node(p, STYLE_NODE_SIZE);
  749.                                 goto done;
  750.                                 break;
  751.  
  752.                         case CHOICE_NODE:
  753.                                 flush_node_list(display_mlist(p));
  754.                                 flush_node_list(text_mlist(p));
  755.                                 flush_node_list(script_mlist(p));
  756.                                 flush_node_list(script_script_mlist(p));
  757.                                 free_node(p, STYLE_NODE_SIZE);/*DIFF*/
  758.                                 goto done;
  759.                                 break;
  760.  
  761.                         case ORD_NOAD:
  762.                         case OP_NOAD:
  763.                         case BIN_NOAD:
  764.                         case REL_NOAD:
  765.                         case OPEN_NOAD:
  766.                         case CLOSE_NOAD:
  767.                         case PUNCT_NOAD:
  768.                         case INNER_NOAD:
  769.                         case RADICAL_NOAD:
  770.                         case OVER_NOAD:
  771.                         case UNDER_NOAD:
  772.                         case VCENTER_NOAD:
  773.                         case ACCENT_NOAD:
  774.                                 if (math_type(nucleus(p)) >= SUB_BOX)
  775.                                         flush_node_list(info(nucleus(p)));
  776.                                 if (math_type(supscr(p)) >= SUB_BOX)
  777.                                         flush_node_list(info(supscr(p)));
  778.                                 if (math_type(subscr(p)) >= SUB_BOX)
  779.                                         flush_node_list(info(subscr(p)));
  780.                                 if (type(p) == RADICAL_NOAD)
  781.                                         free_node(p, RADICAL_NOAD_SIZE);
  782.                                 else if (type(p) == ACCENT_NOAD)
  783.                                         free_node(p, ACCENT_NOAD_SIZE);
  784.                                 else free_node(p, NOAD_SIZE);
  785.                                 goto done;
  786.                                 break;
  787.                         
  788.                         case LEFT_NOAD:
  789.                         case RIGHT_NOAD:
  790.                                 free_node(p, NOAD_SIZE);
  791.                                 goto done;
  792.                                 break;
  793.                         
  794.                         case FRACTION_NOAD:
  795.                                 flush_node_list(info(numerator(p)));
  796.                                 flush_node_list(info(denominator(p)));
  797.                                 free_node(p, FRACTION_NOAD_SIZE);
  798.                                 goto done;
  799.                                 break;
  800.  
  801.                         default:
  802.                                 confusion("flushing");
  803.                                 break;
  804.                         }
  805.                         free_node(p, SMALL_NODE_SIZE);
  806.                         done:;  
  807.                 }
  808.                 p = q;
  809.         }
  810. }
  811.  
  812. ptr
  813. copy_node_list (p)
  814.         ptr             p;
  815. {
  816.         ptr             h;
  817.         ptr             q;
  818.         ptr             r;
  819.         int             words;
  820.  
  821.         h = get_avail();
  822.         q = h;
  823.         while (p != NULL) {
  824.                 words = 1;
  825.                 if (is_char_node(p))
  826.                         r = get_avail();
  827.                 else {
  828.                         switch (type(p))
  829.                         {
  830.                         case HLIST_NODE:
  831.                         case VLIST_NODE:
  832.                         case UNSET_NODE:
  833.                                 r = get_node(BOX_NODE_SIZE);
  834.                                 mem[r + 6] = mem[p + 6];
  835.                                 mem[r + 5] = mem[p + 5];
  836.                                 list_ptr(r) = copy_node_list(list_ptr(p));
  837.                                 words = 5;
  838.                                 break;
  839.                         
  840.                         case RULE_NODE:
  841.                                 r = get_node(RULE_NODE_SIZE);
  842.                                 words = RULE_NODE_SIZE;
  843.                                 break;
  844.  
  845.                         case INS_NODE:
  846.                                 r = get_node(INS_NODE_SIZE);
  847.                                 mem[r + 4] = mem[p + 4];
  848.                                 add_glue_ref(split_top_ptr(p));
  849.                                 ins_ptr(r) = copy_node_list(ins_ptr(p));
  850.                                 words = INS_NODE_SIZE - 1;
  851.                                 break;
  852.  
  853.                         case WHATSIT_NODE:
  854.                                 r = copy_whatsit(p);
  855.                                 break;
  856.                         
  857.                         case GLUE_NODE:
  858.                                 r = get_node(SMALL_NODE_SIZE);
  859.                                 add_glue_ref(glue_ptr(p));
  860.                                 glue_ptr(r) = glue_ptr(p);
  861.                                 leader_ptr(r) = copy_node_list(leader_ptr(p));
  862.                                 break;
  863.                         
  864.                         case KERN_NODE:
  865.                         case MATH_NODE:
  866.                         case PENALTY_NODE:
  867.                                 r = get_node(SMALL_NODE_SIZE);
  868.                                 words = SMALL_NODE_SIZE;
  869.                                 break;
  870.                         
  871.                         case LIGATURE_NODE:
  872.                                 r = get_node(SMALL_NODE_SIZE);
  873.                                 mem[lig_char(r)] = mem[lig_char(p)];
  874.                                 lig_ptr(r) = copy_node_list(lig_ptr(p));
  875.                                 break;
  876.                                 
  877.                         case DISC_NODE:
  878.                                 r = get_node(SMALL_NODE_SIZE);
  879.                                 pre_break(r) = copy_node_list(pre_break(p));
  880.                                 post_break(r) = copy_node_list(post_break(p));
  881.                                 break;
  882.  
  883.                         case MARK_NODE:
  884.                                 r = get_node(SMALL_NODE_SIZE);
  885.                                 add_token_ref(mark_ptr(p));
  886.                                 words = SMALL_NODE_SIZE;
  887.                                 break;
  888.  
  889.                         case ADJUST_NODE:
  890.                                 r = get_node(SMALL_NODE_SIZE);
  891.                                 adjust_ptr(r) = copy_node_list(adjust_ptr(p));
  892.                                 break;
  893.                         
  894.                         default:
  895.                                 confusion("copying");
  896.                                 break;
  897.                         }
  898.                 }
  899.                 while (words > 0) {
  900.                         decr(words);
  901.                         mem[r + words] = mem[p + words];
  902.                 }
  903.                 link(q) = r;
  904.                 q = r;
  905.                 p = link(p);
  906.         }
  907.         link(q) = NULL;
  908.         q = link(h);
  909.         free_avail(h);
  910.         return q;
  911. }
  912.